﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
using System.Web.UI;
using IRC.IRepairClouds.WebClient.Controls.Common;

namespace IRC.IRepairClouds.WebClient
{
    public static class Extensions
    {
        public static bool IsNullOrTrimEmpty(this string str)
        {
            return str == null || str.Length == 0 || str.Trim().Length == 0;
        }

        public static int? ToInt(this double? value)
        {
            if (value == null)
                return null;
            return (int)value;
        }

        public static int? ToInt(this RadComboBox ddl)
        {
            if (string.IsNullOrEmpty(ddl.SelectedValue))
                return null;
            int res;
            if (!int.TryParse(ddl.SelectedValue, out res))
                return null;
            return res;
        }

        public static string ToStr(this RadComboBox ddl)
        {
            if (string.IsNullOrEmpty(ddl.SelectedValue))
                return null;
            return ddl.SelectedValue;
        }

        public static DateTime? ToDate(this RadDatePicker rdp)
        {
            if (rdp.SelectedDate == null)
                return null;
            return rdp.SelectedDate.Value.Date;
        }

        //public static Guid? ToGuid( this string str)
        //{
        //    if (string.IsNullOrEmpty(str))
        //        return null;
        //    try {
        //        Guid g = new Guid(str);
        //        return g;
        //    }
        //    catch {
        //    }
        //    return null;
        //}


        public static Control FindInHierchy(this Control owner, string id)
        {
            if (owner == null)
                return null;
            if (owner.ID == id)
                return owner;
            return FindInHierchy(owner.Controls, id);
        }

        private static Control FindInHierchy(ControlCollection controls, string id)
        {
            if (controls == null || controls.Count == 0)
                return null;
            foreach (Control c in controls)
            {
                if (c.ID == id)
                    return c;
                Control ch = FindInHierchy(c.Controls, id);
                if (ch != null)
                    return ch;
            }
            return null;
        }

        public static T FindInHierchy<T>(this Control owner, string id) where T : Control
        {
            Control c = FindInHierchy(owner, id);
            if (c == null)
                return null;
            return (T)c;
        }

        public static RadSiteMapNode FindNodeByValue(this RadSiteMap siteMap, string value)
        {
            return FindNodeBy(siteMap, i => i.Value == value);
            //return FindNodeByValueInternal(siteMap.Nodes, value);
        }

        //private static RadSiteMapNode FindNodeByValueInternal(RadSiteMapNodeCollection nodes, string value)
        //{
        //    if (nodes == null || nodes.Count == 0)
        //        return null;
        //    foreach (RadSiteMapNode n in nodes) {
        //        if (n.Value == value)
        //            return n;
        //        var chn = FindNodeByValueInternal(n.Nodes, value);
        //        if (chn != null)
        //            return chn;
        //    }
        //    return null;
        //}

        public static RadSiteMapNode FindNodeByUrl(this RadSiteMap siteMap, string url)
        {
            return FindNodeBy(siteMap, i => i.NavigateUrl == url);
        }

        public static RadSiteMapNode FindNodeBy(this RadSiteMap siteMap, Func<RadSiteMapNode, bool> cond)
        {
            return FindNodeByInternal(siteMap.Nodes, cond);
        }

        private static RadSiteMapNode FindNodeByInternal(RadSiteMapNodeCollection nodes, Func<RadSiteMapNode, bool> cond)
        {
            if (nodes == null || nodes.Count == 0)
                return null;
            foreach (RadSiteMapNode n in nodes)
            {
                if (cond(n))
                    return n;
                var chn = FindNodeByInternal(n.Nodes, cond);
                if (chn != null)
                    return chn;
            }
            return null;
        }




        public static RadSiteMapNode FindNodeByUrlBestMatch(this RadSiteMap siteMap, string url)
        {
            UrlParser up = new UrlParser(url.ToLower());
            RadSiteMapNode bm = null;
            int matchLevel = -1;
            FindNodeByUrlBestMatchInternal(siteMap.Nodes, up, ref bm, ref matchLevel);
            return bm;
        }

        public static RadSiteMapNode FindNodeByUrlBestMatch(this RadSiteMap siteMap, UrlParser url)
        {
            RadSiteMapNode bm = null;
            int matchLevel = -1;
            FindNodeByUrlBestMatchInternal(siteMap.Nodes, url, ref bm, ref matchLevel);
            return bm;
        }

        private static void FindNodeByUrlBestMatchInternal(RadSiteMapNodeCollection items, UrlParser url, ref RadSiteMapNode bestmatch, ref int matchLevel)
        {
            if (items == null || items.Count == 0)
                return;
            foreach (RadSiteMapNode n in items)
            {
                if (n.Visible && !string.IsNullOrEmpty(n.NavigateUrl))
                {
                    var ap = Utils.MakeAbsolutePath(n.NavigateUrl);
                    UrlParser up = new UrlParser(ap.ToLower());
                    if (up.Url == url.Url)
                    {
                        int tm = 0;
                        foreach (var q in up.Queries)
                        {
                            string val;
                            if (url.Queries.TryGetValue(q.Key, out val))
                            {
                                if (val == q.Value)
                                    tm++;
                            }
                        }
                        if (tm > matchLevel && tm == up.Queries.Count)
                        {
                            matchLevel = tm;
                            bestmatch = n;
                        }
                    }
                }
                FindNodeByUrlBestMatchInternal(n.Nodes, url, ref bestmatch, ref matchLevel);
            }
        }






        public static RadSiteMapNode FindNodeByUrlMatch(this RadSiteMap siteMap, UrlParser url)
        {
            RadSiteMapNode bm = null;
            int matchLevel = -1;
            FindNodeByUrlMatchInternal(siteMap.Nodes, url, ref bm, ref matchLevel);
            return bm;
        }

        private static void FindNodeByUrlMatchInternal(RadSiteMapNodeCollection items, UrlParser url, ref RadSiteMapNode bestmatch, ref int matchLevel)
        {
            if (items == null || items.Count == 0)
                return;
            foreach (RadSiteMapNode n in items)
            {
                if (!string.IsNullOrEmpty(n.NavigateUrl))
                {
                    var ap = Utils.MakeAbsolutePath(n.NavigateUrl);
                    UrlParser up = new UrlParser(ap.ToLower());
                    if (up.Url == url.Url)
                    {
                        int tm = 0;
                        foreach (var q in up.Queries)
                        {
                            string val;
                            if (url.Queries.TryGetValue(q.Key, out val))
                            {
                                if (val == q.Value)
                                    tm++;
                            }
                        }
                        if (tm > matchLevel && tm == up.Queries.Count)
                        {
                            matchLevel = tm;
                            bestmatch = n;
                        }
                    }
                }
                FindNodeByUrlMatchInternal(n.Nodes, url, ref bestmatch, ref matchLevel);
            }
        }



        public static void ClientHidePager(this RadGrid radGrid)
        {
            //radGrid.ShowStatusBar = true;
            if (radGrid != null)
                radGrid.ItemCreated += new GridItemEventHandler(ClientPrepare_RadGrid_ItemCreated);
        }

        private static void ClientPrepare_RadGrid_ItemCreated(object sender, GridItemEventArgs e)
        {
            if (e.Item is GridDataItem)
                e.Item.Display = false;
            GridPagerItem pi;
            if ((pi = e.Item as GridPagerItem) != null)
            {
                if (pi.PagerContentCell.Controls.Count > 0)
                {
                    var t = pi.PagerContentCell.Controls[0] as Table;
                    if (t.Rows.Count > 0)
                    {
                        var r = t.Rows[0];
                        if (r.Cells.Count > 0)
                        {
                            foreach (TableCell c in r.Cells)
                            {
                                if (c.CssClass != null && c.CssClass.Contains("rgPagerCell"))
                                {
                                    c.Style.Add(HtmlTextWriterStyle.Visibility, "hidden");
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        public static void ClientHidePagerRow(this RadGrid radGrid)
        {
            //radGrid.ShowStatusBar = true;
            if (radGrid != null)
                radGrid.ItemCreated += new GridItemEventHandler(ClientHidePagerRow_RadGrid_ItemCreated);
        }

        private static void ClientHidePagerRow_RadGrid_ItemCreated(object sender, GridItemEventArgs e)
        {
            if (e.Item is GridDataItem)
                e.Item.Display = false;
            GridPagerItem pi;
            if ((pi = e.Item as GridPagerItem) != null)
            {
                e.Item.Display = false;
            }
        }
        public static void RemoveTabFull(this RadTabStrip tabStrip, string tabValue)
        {
            if (tabStrip != null && !string.IsNullOrEmpty(tabValue))
            {
                var tab = tabStrip.FindTabByValue(tabValue);
                if (tab != null)
                {
                    var p = tabStrip.Tabs.IndexOf(tab);
                    if (p != -1)
                    {
                        tabStrip.Tabs.RemoveAt(p);
                        if (tabStrip.MultiPage != null && tabStrip.MultiPage.PageViews.Count > p)
                            tabStrip.MultiPage.PageViews.RemoveAt(p);
                    }
                }
            }
        }

        public static bool TabExists(this RadTabStrip tabStrip, string tabValue)
        {
            if (tabStrip != null && !string.IsNullOrEmpty(tabValue))
            {
                var tab = tabStrip.FindTabByValue(tabValue);
                if (tab != null)
                    return true;
            }
            return false;
        }

        public static void Bind<T>(this RadComboBox combobox, IEnumerable<T> dataSource, Func<T, string> textSelector, Func<T, string> valueSelector, bool addEmpty)
        {
            combobox.Items.Clear();
            if (addEmpty)
            {
                combobox.Items.Add(new RadComboBoxItem("", ""));
            }
            foreach (var i in dataSource)
                combobox.Items.Add(new RadComboBoxItem(textSelector(i), valueSelector(i)));
        }

        public static void Bind<T>(this RadComboCheckBoxList combobox, IEnumerable<T> dataSource, Func<T, string> textSelector, Func<T, string> valueSelector)
        {
            combobox.Items.Clear();
            foreach (var i in dataSource)
                combobox.Items.Add(new RadComboCheckBoxList.Item
                {
                    Name = textSelector(i),
                    Value = valueSelector(i)
                });
        }

    }
}